package com.aaa.common.util;

import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * fileName:MyCustomCache
 * description:
 * author:zz
 * createTime:2020/7/30 14:07
 * version:1.0.0
 */
public class MyCustomCache  implements Cache{

    //jedis链接工厂类
    private  static JedisConnectionFactory jedisConnectionFactory;

    //缓存对象的唯一标识
    private String id;

    //读读共享  读写互斥  写读互斥  写写互斥
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    /**
     * 空构造
     */
    public MyCustomCache() {
    }

    /**
     * 构造方法，给id赋值
     * @param id
     */
    public MyCustomCache(String id) throws Exception {
        if(id==null){
            throw  new Exception("id不能为空");
        }
        this.id = id;
    }

    /**
     * 通过静态方法，直接给静态属性赋值，不用使用对象，使用类名称可以直接调用
     * @param jedisConnectionFactory
     */
    public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory){
       // System.out.println("初始化。。。。。。。。。。。。。。。。。。");
        MyCustomCache.jedisConnectionFactory = jedisConnectionFactory;
    }

    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public void putObject(Object key, Object value) {
        RedisConnection connection = null;
        try {
            //获取连接
            connection = jedisConnectionFactory.getConnection();
            //实例化Redis序列化类
            JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
            //序列化结果就是一个字节数组
            byte[] keyS = jdkSerializationRedisSerializer.serialize(key);
            byte[] valS = jdkSerializationRedisSerializer.serialize(value);
            //保存数据
            connection.set(keyS,valS);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(connection!=null){
                connection.close();
            }
        }

    }

    @Override
    public Object getObject(Object key) {
        RedisConnection connection = null;
        try {
            //获取连接
            connection = jedisConnectionFactory.getConnection();
            //实例化Redis序列化类
            JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
            //序列化key
            byte[] keyS = jdkSerializationRedisSerializer.serialize(key);
            //根据序列化后的key获取序列化后的值
            byte[] valS = connection.get(keyS);
            //执行反序列化，返回原来的对象
            return  jdkSerializationRedisSerializer.deserialize(valS);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(connection!=null){
                connection.close();
            }
        }
        return null;
    }

    @Override
    public Object removeObject(Object key) {
        RedisConnection connection = null;
        try {
            //获取连接
            connection = jedisConnectionFactory.getConnection();
            //实例化Redis序列化类
            JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
            //序列化key
            byte[] keyS = jdkSerializationRedisSerializer.serialize(key);
            //connection.del(keyS);
            // expireAt  0 所有版本  让失效不是立马删除，而是等一定时间间隔，再去批量删除
           return connection.expireAt(keyS,0);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(connection!=null){
                connection.close();
            }
        }
        return false;
    }

    @Override
    public void clear() {
        RedisConnection connection = null;
        try {
            //获取连接
            connection = jedisConnectionFactory.getConnection();
             //清空当前库
             connection.flushDb();
             //清空所有库
             connection.flushAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(connection!=null){
                connection.close();
            }
        }

    }

    @Override
    public int getSize() {
        RedisConnection connection = null;
        try {
            //获取连接
            connection = jedisConnectionFactory.getConnection();
            //清空当前库
            Long aLong = connection.dbSize();
            return Integer.valueOf(aLong.toString());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(connection!=null){
                connection.close();
            }
        }
        return 0;
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        return readWriteLock;
    }
}
